﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using GGJ_DKG.Objects;
using GGJ_DKG.Menu;
using GGJ_DKG.Managers;

namespace GGJ_DKG.Menu
{
    class Level : Screen
    {
        #region Variables
        public bool paused = false;
        public bool gameOver = false;

        #region Player
        Player player;
        public static Rectangle playerRect;
        public float playerRotation;
        public float meters;
        int meterDesc = 2;
        public static bool playerDown;
        private bool playerGoUp;
        public bool fillingAir;
        #endregion

        #region BackGround Color Var
        Vector4 RGBA;
        SceneryManager scenery;
        #endregion

        #region HUD
        SpriteFont heartRate;
        Object2D HUD;
        public string BPMstring;
        string meterString;
        public Vector4 airColor;
        public Vector2 airScale;
        Object2D airLevel;
        Object2D pausedGraphic;
        Object2D gameOverGraphic;
        #endregion

        #region Timers
        int seconds;
        int milSecond;
        float BTpM; //Buttons per minute
        float BPM;
        bool lastBeat;
        #endregion
        #endregion

        public Level(Texture2D texture, Vector2 position, ContentManager Content, GraphicsDeviceManager graphics)
            : base(texture, position)
        {

            #region Player
            player = new Player(Content.Load<Texture2D>("SpritesPlayer/swimsheet_3"));
            player.Rotation = 0;
            player.Alpha = 1;
            playerRect = player.Colisao;
            #endregion

            #region Scenery
            scenery = new SceneryManager(Content, graphics);
            RGBA = new Vector4(100, 150, 250, 100);
            if(SoundManager.CheckList("SoundEffect", "heart1"))
                SoundManager.AddSound("heart1", Content.Load<SoundEffect>("Sound/heartbeat1"));
            if (SoundManager.CheckList("SoundEffect", "heart2"))
                SoundManager.AddSound("heart2", Content.Load<SoundEffect>("Sound/heartbeat2"));
            #endregion

            #region HUD

            HUD = new Object2D(Content.Load<Texture2D>("HUD/HUD"));
            HUD.Position = new Vector2(HUD.Texture.Width / 2, HUD.Texture.Height / 2);

            airScale = new Vector2(1f, 0.85f);
            airColor = new Vector4(0, 254, 0, 255);
            airLevel = new Object2D(Content.Load<Texture2D>("HUD/airBar"));
            airLevel.Position = new Vector2(59, 23);
            airLevel.MiddlePoint = new Vector2(airLevel.Texture.Width, airLevel.MiddlePoint.Y);
            airLevel.ObjectColor = Color.FromNonPremultiplied((int)airColor.X, (int)airColor.Y, (int)airColor.Z, (int)airColor.W);

            BTpM = 0;
            BPM = ((Input.buttonPresses * (meterDesc / 100)) + 70 + (meterDesc / 50));
            Input.buttonPresses = 0;
            heartRate = Content.Load<SpriteFont>("HUD/HUDfont");

            pausedGraphic = new Object2D(Content.Load<Texture2D>("Menu/paused"));
            pausedGraphic.Position = new Vector2(Game1.Self.Window.ClientBounds.Width / 2,
                Game1.Self.Window.ClientBounds.Height / 2);

            gameOverGraphic = new Object2D(Content.Load<Texture2D>("Menu/Gameover"));
            gameOverGraphic.Position = new Vector2(Game1.Self.Window.ClientBounds.Width / 2,
                Game1.Self.Window.ClientBounds.Height / 2);
            #endregion

            #region Game1
            Game1.Self.playerRect = playerRect;
            Game1.Self.playerRotation = playerRotation;
            Game1.Self.meters = meters;
            Game1.Self.playerDown = playerDown;
            Game1.Self.fillingAir = fillingAir;
            Game1.Self.BPMstring = BPMstring;
            Game1.Self.airColor = airColor;
            #endregion

        }
        public override void Load(ContentManager Content, GameWindow Window)
        {

        }
        public override void Update(GameTime gameTime)
        {
            if (gameOver && Input.GetDown(Keys.Enter))
            {
                Game1.Self.currentScreenSelect = Game1.Screens.MENU;
            }
            #region Paused
            if (!paused)
            {
                playerRect = player.Colisao;

                player.Update(gameTime);
                rpmController(gameTime);

                #region Down movement
                if (Input.GetDown(Keys.Down))
                {
                    playerDown = true;
                    playerGoUp = false;
                }
                if (playerDown)
                {
                    if (player.Rotation < MathHelper.ToRadians(90))
                        player.Rotation += MathHelper.ToRadians(1);
                    else if (player.Rotation >= MathHelper.ToRadians(90))
                        meters += 0.007f * (BTpM / 180);
                }
                else
                {
                    if (player.Rotation > MathHelper.ToRadians(0))
                        player.Rotation -= MathHelper.ToRadians(1);

                    if (meters > 0)
                        meters -= 0.02f;
                }
                #endregion

                #region Background
                if (player.Rotation >= MathHelper.ToRadians(88)
                    && playerDown && meterDesc == Math.Truncate(meters))
                {
                    //o cenario desloca para cima
                        if (RGBA.X > 0)
                            RGBA.X--;
                        else if (RGBA.X == 0 && RGBA.Y > 0)
                            RGBA.Y--;
                        else if (RGBA.Y == 0 && RGBA.Z > 0)
                            RGBA.Z--;
                        meterDesc = (int)Math.Truncate(meters) + 2;
                }
                else if (player.Rotation <= MathHelper.ToRadians(88)
                    && meterDesc - 2 == (int)Math.Truncate(meters))
                {
                    //o cenario baixo
                        if (RGBA.Z < 250)
                            RGBA.Z++;
                        else if (RGBA.Y < 150 && RGBA.Z == 250)
                            RGBA.Y++;
                        else if (RGBA.Y == 150 && RGBA.X < 100)
                            RGBA.X++;
                        meterDesc = (int)Math.Truncate(meters);
                }
                Console.WriteLine(RGBA.X.ToString() + " " + RGBA.Y.ToString() + " " + RGBA.Z.ToString());
                scenery.Update(gameTime);
                #endregion

                playerRotation = player.Rotation;

                #region HeartBeat
                BPMstring = BPM.ToString();
                meterString = Math.Truncate(meters).ToString();
                if (gameTime.TotalGameTime.Milliseconds >= milSecond 
                    && !gameOver && Game1.Self.SoundOn)
                {
                    milSecond += (int)((1000 * 60) / BPM);
                    if (milSecond > 1000) milSecond = 990;
                    if (lastBeat)
                    {
                        SoundManager.PlaySound("heart1");
                        lastBeat = !lastBeat;
                    }
                    else
                    {
                        SoundManager.PlaySound("heart2");
                        lastBeat = !lastBeat;
                    }
                }
                #endregion

                #region Game1

                Game1.Self.playerRect = player.Colisao;
                Game1.Self.playerRotation = playerRotation;
                Game1.Self.meters = meters;
                Game1.Self.playerDown = playerDown;
                fillingAir = Game1.Self.fillingAir;
                Game1.Self.BPMstring = BPMstring;
                Game1.Self.airColor = airColor;

                #endregion
                if (Input.GetDown(Keys.Enter))
                {
                    paused = true;
                }
            }
            else if (!gameOver)
            {
                if (Input.GetDown(Keys.Enter))
                {
                    paused = false;
                }
                else if (Input.GetDown(Keys.Escape))
                {
                    Game1.Self.currentScreenSelect = Game1.Screens.MENU;
                }
            }
            #endregion
        }

        public override void Draw(SpriteBatch spriteBatch, GameTime gameTime)
        {

            scenery.Draw(spriteBatch, RGBA, gameTime);
            player.Draw(gameTime, spriteBatch);
            #region HUD
            HUD.Draw(spriteBatch);
            spriteBatch.DrawString(heartRate, BPMstring, new Vector2(27, 36), Color.Red);
            spriteBatch.DrawString(heartRate, meterString, new Vector2(125, 16), Color.Red);
            airLevel.Draw(spriteBatch);
            #endregion
            if (paused && !gameOver)
                pausedGraphic.Draw(spriteBatch);
            if (gameOver)
                gameOverGraphic.Draw(spriteBatch);
        }

        public void rpmController(GameTime gameTime)
        {
            if (gameTime.TotalGameTime.Seconds != seconds)
            {
                if (seconds == 60)
                {
                    seconds = 0;
                }
                else
                {
                    seconds = gameTime.TotalGameTime.Seconds;
                }
                milSecond = 0;
                BTpM = Input.buttonPresses * 60;
                BPM = (int)Math.Truncate((Input.buttonPresses * (meters / 400)) + 70);
                Input.buttonPresses = 0;

                if (seconds % 2.5f == 0 && playerGoUp)
                {
                    playerDown = false;
                }
                if (seconds % 2 == 0 &&
                    !(Input.GetKey(Input.key.Down)))
                {
                    playerGoUp = true;
                }
                #region Air
                if (!fillingAir)
                {
                    airScale.X -= 0.005f * (BPM / 50);
                    airScale -= Game1.Self.airScale;
                }
                else
                {
                    if (airScale.X < 1)
                    {
                        airScale.X = 1f;
                        airColor = new Vector4(0, 254, 0, 255);
                    }
                }
                if (airScale.X < 0.5f)
                {

                    if (airColor.Y > 0)
                    {
                        airColor.Y -= 12;
                        airColor.X += 12;
                    }
                    else if (airColor.X > 0)
                    {
                        airColor.X -= 6;
                    }
                }
                airLevel.ScaleVector = airScale;
                airLevel.ObjectColor = Color.FromNonPremultiplied(
                    (int)airColor.X,
                    (int)airColor.Y,
                    (int)airColor.Z,
                    (int)airColor.W);

                if (airColor.X <= 30 && airScale.X < 0.1f)
                {
                    gameOver = true;
                    paused = false;
                    if (!SoundManager.CheckSong("gameOver") && Game1.Self.SoundOn)
                    {
                        SoundManager.StopMusic();
                        SoundManager.PlayMusic("gameOver");
                    }
                }
                #endregion
            }
        }
        //end class
    }
}